<?php
namespace app\home\controller;

use app\home\model\RedEnvelope;
use think\Db;
/**
 * @title 定时任务
 * @description 接口说明
 * @group 西红柿
 */
class TimingTask
{
	public static $returnType       = 4;							// 红包过期退回
	public static $exemptLevel      = 30;							// 免分润级数
	public static $snatchLevel      = 3;							// 抢分润级数
	public static $sendLevel      	= 3;							// 发分润级数
	/**
     * 过期红包退回
     * @description 每分钟执行一次，一次处理100条数据
     * @param 
     * @return 
     */
	public function RedEnvelopesReturn()
	{
		$expiredEnvelopes = Db::name('red_envelope')->where('left_num','<>',0)->where(['overdue' => 0])->limit(100)->select();
		$updateReIds 	= [];																										// 过期红包ids			
		$userArr 		= [];																										// 
		$solitaireArr 	= [];																										// 接龙红包
		$rN 			= 0;																										//
		$cN 			= 0;																										//
		foreach ($expiredEnvelopes as $key => $value) 
		{
			# 判断是否过期
			$isOverdue = (strtotime($value['create_time']) + $value['term']) - time();
			if ($isOverdue <= 0) 
			{
				array_push($updateReIds,$value['re_id']);
				if ($value['room_type'] ==2) array_push($solitaireArr,$value['re_id']);
				$returnMoney = $value['room_type']==1 ? $value['left_money'] : $value['money']; 
				array_push($userArr, ['uid' => $value['uid'], 'money' => $returnMoney, 'uname' => $value['uname'], 're_id' => $value['re_id'], 'room_id' => $value['room_id']]);
			}
		}
		Db::startTrans();
		try {

			$upN 	= Db::name('red_envelope')->whereIn('re_id',$updateReIds)->update(['overdue' => 1, 'update_time' => date('Y-m-d H:i:s')]);
			dump('修改红包状态'.$upN.'条');
			foreach ($userArr as $key => $value) 
			{
				# 过期未领完退币
				if($value['uid'] == 0) continue;
				$haveU = Db::name('user')->get($value['uid']);
				if (!$haveU) continue;
				$userN 	= Db::name('user')->where(['user_id' => $value['uid']])->setInc('user_gold',$value['money']);
				if (!$userN) 
				{
					// dump($value);
					Db::rollback();
					echo '数据操作失败1';

				}
				$logArr['user_id'] 		= $value['uid']; 
				$logArr['user_name']	= $value['uname'];
				$logArr['red_id']		= $value['re_id'];
				$logArr['room_id']		= $value['room_id'];
				$logArr['snatch_money']	= $value['money'];
				$logArr['type']			= static::$returnType;
				$logArr['create_time']	= date('Y-m-d H:i:s');
				$logN = Db::name('game_log')->insert($logArr);
				if (!$logN) 
				{
					Db::rollback();
					echo '数据操作失败2';
				}
				$rN++;
			}
			dump('未领完退回'.$rN.'条');
			# 接龙未抢完收币
			$snatchLog = Db::name('snatch_log')->where('uid','<>',0)->whereIn('re_id',$solitaireArr)->select();
			foreach ($snatchLog as $key => $value) 
			{
				if(!Db::name('user')->get($value['uid'])) continue;
				$colletN = Db::name('user')->where(['user_id' => $value['uid']])->setDec('user_gold',$value['money']);
				if (!$colletN) 
				{
					Db::rollback();
					echo '数据操作失败3';
				}
				$cN++;
			}
			dump('红包未领完过期收回抢到'.$cN.'条');
			Db::commit();
			echo '退币成功';
			
		} catch (Exception $e) {
			Db::rollback();
			echo '数据操作失败4';
			var_dump($e);
		}
		

	}


/**
     * 添加分润记录
     * @description 查询有效发包记录，分润,一小时执行一次
     *
     */
	public function profitProfit1()
	{
		# 查出所有有效红包，找到发包者上级按照比例添加发分润记录，根据免死抢到金额添加免分润表
		# 流水分润--发
		// die;
		$sendEnvelopes 	= Db::name('red_envelope')->where('left_num = 0 and uid <> 0')->where('share_status = 0')->limit(100)->select();
		// dump($sendEnvelopes);
		$uidArr 		= [];
		$redIds 		= [];
		$redMoney 		= [];
		$ridUid 		= [];
		$systemInfo 	= Db::name('config')->find();
		$systemProfit 	= explode(',', $systemInfo['system_profit']);						// 免分润比例
		$sendProfit 	= $systemInfo['send_profit'];										// 发抢分润比例
		$sharePArr 		= [];
		foreach ($sendEnvelopes as $key => $value) 
		{
			array_push($uidArr, $value['uid']);
			array_push($redIds, $value['re_id']);
			$redMoney[$value['re_id']] = ['uid' =>$value['uid'], 'money' => $value['money']];

		}
		echo '所有发包用户<br/>';
		var_dump($uidArr);echo '<br/>';
		$userArr 	= Db::name('user')->where('user_id','in',$uidArr)->column('level_path','user_id');
		$sId = Db::name('user')->where('user_id','in',$uidArr)->where('level_path != null')->column('user_id');
		echo '有上级用户';
		var_dump($sId);echo '<br>';
		if ($sId)
		{
			foreach ($redMoney as $key => $value) 
			{
				if (in_array($value['uid'], $sId)) $ridUid[$value['uid']] = $key;
			}
			var_dump($ridUid);echo '<br>';
			$snatchLog 	= Db::name('snatch_log')->where('re_id','in',$ridUid)->where('uid',0)->select();				// 平台抢包记录
			var_dump($snatchLog);die;
		}
		else
		{
			$snatchLog = [];
		}
		
		$uSnatchLog = Db::name('snatch_log s')->where('s.re_id','in',$ridUid)->where('s.status',0)->where('s.uid','<>',0)->join('user u','u.user_id=s.uid')->field('u.*,s.*')->where('u.level_path != null')->select();		// 用户抢包记录
		if (count($uSnatchLog))
		{
			foreach ($uSnatchLog as $ukey => $uval) 
			{
				$uSInfo[$uval['uid']] = ['uid' => $uval['uid'], 'sl_id' => $uval['sl_id'], 're_id' => $uval['re_id'],'money' => $uval['money'], 'level_path' => $uval['level_path']];
			}
		}
		
		# 免分润
		$doN = 0;
		Db::startTrans();
        try{
	        	if ($snatchLog)
	        	{
	        		dump($snatchLog);
	        		foreach ($snatchLog as $sk => $sv) 
					{
						$uP = $userArr[$redMoney[$sv['re_id']]['uid']];					// 发用户上级完整路径
						# 找发包者上级
						$levelIds = array_reverse(explode(',', substr($uP,1)));
						foreach ($levelIds as $lk => $lv) 
						{
							if ($lk < static::$exemptLevel)
							{
								# 免死分润（只有30级）
								$level 	= explode('-', $systemProfit[$lk]);
								$pMoney = $level[1] * $sv['money'] * 0.2;
								$sendPArr = [
									'user_id' 		=> $lv,
									'type' 			=> 1,
									'level' 		=> $level[0],
									'note' 			=> '免 '.$level[0].' 分润',
									'money' 		=> $pMoney,
									'create_time' 	=> date('Y-m-d H:i:s')
								];
								/******************好像没用******************/
			                    $red_packet = [
			                        'user_id' 	=>$lv,
			                        'type' 		=>1,
			                        'money'		=>$pMoney,
			                    ];
			                    /******************好像没用******************/
			                    $addInfo = Db::name('share_profit')->insert($sendPArr);
			                    if (!$addInfo)
			                    {
			                        Db::rollback();
			                        return json_error('操作失败1!');
			                    }else{echo '免分润添加成功';}
		                        /*************************好像没用开始*******************************/
		                        /*$addRedPacket= Db::name('red_packet')->insert($red_packet);
		                        if (!$addRedPacket){
		                            Db::rollback();
		                            return json_error('操作失败2!');
		                        }
		                        /*************************好像没用结束*******************************/
			                }
			                # 发分润（只有三级）
			                if ($lk < static::$sendLevel)
			                {
			                	$sMoney = $redMoney[$sv['re_id']]['money'] * $sendProfit;
			                    $faPArr = [
			                        'user_id' 		=> $lv,
			                        'type' 			=> 2,
			                        'level'			=> $level[0],
			                        'note' 			=> '发 '.$level[0].' 分润',
			                        'money' 		=> $sMoney,
			                        'create_time' 	=> date('Y-m-d H:i:s')
			                    ];
			                    $red_packet = [
			                        'user_id' =>$lv,
			                        'type' =>1,
			                        'money'=>$sMoney,
			                    ];
		                        $addInfo = Db::name('share_profit')->insert($faPArr);
		                        if (!$addInfo){
		                            Db::rollback();
		                            return json_error('操作失败3!');
		                        }else{echo '发分润添加成功';}
		                        /*$addRedPacket= Db::name('red_packet')->insert($red_packet);
		                        if (!$addRedPacket){
		                            Db::rollback();
		                            return json_error('操作失败4!');
		                        }*/
			                }
						}
						$u2++;
	        		}
	        		echo '发免'.$u2.'条';
	        	}

	        	if ($uSnatchLog)
	        	{
	        		dump($uSnatchLog);
					# 用户抢包分润
					$sPArr = [];
					$suArr = [];
					foreach ($uSnatchLog as $uSnatK => $uSnatV) 
					{
						# 找到当前红包用户抢记录
						if ($sv['re_id'] == $uSnatV['re_id'])
						{
							if (!$uSnatV['level_path']) continue;
							$pIds 		= array_reverse(explode(',', substr($uSnatV['level_path'],1)));
							$someIds 	= array_slice($pIds, 0, static::$snatchLevel);
							$pMoney 	= $uSnatV['money'] * $sendProfit;
							foreach ($someIds as $key => $value) 
							{
								$sPArr[] 	= [
					                    'user_id' 		=> $value,
					                    'type' 			=> 4,
					                    'level'			=> ++$key,
					                    'note' 			=> '抢 '.$key.' 分润',
					                    'money' 		=> $pMoney,
					                    'create_time' 	=> date('Y-m-d H:i:s')
					                ];
							}
							$sPN = Db::name('share_profit')->insertAll($sPArr);
				            if ($sPN) {$suArr[] = $uSnatV['sl_id'];echo '抢分润添加成功';}else{Db::rollback();return json_error('数据操作失败5');}
						}
						$u1++;
					}
					echo '抢包分润'.$u1++;
				}
				$sn = Db::name('snatch_log')->where('re_id','in',$redIds)->setField('status',1);
				if (!$sn){Db::rollback();return json_error('数据操作失败6');}
				$redN = Db::name('red_envelope')->where('re_id','in',$redIds)->update(['share_status' => 1]);

				if (!$redN) 
				{
					Db::rollback();return json_error('数据操作失败7');
				}
				else
				{	echo '红包表分润状态修改成功<br/>';Db::commit();
					# 处理发免条数
					$doN++;
				}

		} catch (Exception $e) {
			Db::rollback();
		}
		
		echo '处理分润免润条数--抢包条数'.$sn.',红包条数--'.$redN;
	}


	/**
     * 添加分润记录
     * @description 查询有效发包记录，分润,一小时执行一次
     *
     */
	public function profitProfit()
	{
		# 查出所有有效红包，找到发包者上级按照比例添加发分润记录，根据免死抢到金额添加免分润表
		# 流水分润--发
		$sendEnvelopes 	= Db::name('red_envelope')->where('left_num = 0 and uid <> 0')->where('share_status = 0')->limit(100)->select();
		/*dump(Db::name('red_envelope')->getLastSql());
		echo '红包';
		dump($sendEnvelopes);
		echo '红包';*/
		$uidArr 		= [];
		$redIds 		= [];
		$redMoney 		= [];
		$systemInfo 	= Db::name('config')->find();
		$systemProfit 	= explode(',', $systemInfo['system_profit']);
		$sendProfit 	= $systemInfo['send_profit'];
		$sharePArr 		= [];
		foreach ($sendEnvelopes as $key => $value) 
		{
			array_push($uidArr, $value['uid']);
			array_push($redIds, $value['re_id']);
			$redMoney[$value['re_id']] = ['uid' =>$value['uid'], 'money' => $value['money']];
		}
		$userArr 	= Db::name('user')->where('user_id','in',$uidArr)->column('level_path','user_id');
		$snatchLog 	= Db::name('snatch_log')->where('re_id','in',$redIds)->where('uid',0)->select();				// 平台抢包记录
		$uSnatchLog = Db::name('snatch_log s')->where('s.re_id','in',$redIds)->where('s.status',0)->where('s.uid','<>',0)->join('user u','u.user_id=s.uid')->field('u.*,s.*')->select();		// 用户抢包记录
		foreach ($uSnatchLog as $ukey => $uval) 
		{
			$uSInfo[$uval['uid']] = ['uid' => $uval['uid'], 'sl_id' => $uval['sl_id'], 're_id' => $uval['re_id'],'money' => $uval['money'], 'level_path' => $uval['level_path']];
		}
		// dump($uSInfo);die;
		# 免分润
		$doN = 0;
		// dump($snatchLog);
		Db::startTrans();
        try{
			foreach ($snatchLog as $sk => $sv) 
			{
				$uP = $userArr[$redMoney[$sv['re_id']]['uid']];					// 发用户上级完整路径
				# 找发包者上级
				$levelIds = array_reverse(explode(',', substr($uP,1)));
				foreach ($levelIds as $lk => $lv) 
				{
					if ($lk < static::$exemptLevel)
					{
						# 免死分润（只有30级）
						$level 	= explode('-', $systemProfit[$lk]);
						$pMoney = $level[1] * $sv['money'] * 0.2;
						$sendPArr = [
							'user_id' 		=> $lv,
							'type' 			=> 1,
							'level' 		=> $level[0],
							'note' 			=> '免 '.$level[0].' 分润',
							'money' 		=> $pMoney,
							'create_time' 	=> date('Y-m-d H:i:s')
						];
						/******************好像没用******************/
	                    $red_packet = [
	                        'user_id' 	=>$lv,
	                        'type' 		=>1,
	                        'money'		=>$pMoney,
	                    ];
	                    /******************好像没用******************/
	                    $addInfo = Db::name('share_profit')->insert($sendPArr);
	                    if (!$addInfo)
	                    {
	                        Db::rollback();
	                        return json_error('操作失败1!');
	                    }else{echo '免分润添加成功';}
                        /*************************好像没用开始*******************************/
                        /*$addRedPacket= Db::name('red_packet')->insert($red_packet);
                        if (!$addRedPacket){
                            Db::rollback();
                            return json_error('操作失败2!');
                        }
                        /*************************好像没用结束*******************************/
	                }
	                # 发分润（只有三级）
	                if ($lk < static::$sendLevel)
	                {
	                	$sMoney = $redMoney[$sv['re_id']]['money'] * $sendProfit;
	                    $faPArr = [
	                        'user_id' 		=> $lv,
	                        'type' 			=> 2,
	                        'level'			=> $level[0],
	                        'note' 			=> '发 '.$level[0].' 分润',
	                        'money' 		=> $sMoney,
	                        'create_time' 	=> date('Y-m-d H:i:s')
	                    ];
	                    $red_packet = [
	                        'user_id' =>$lv,
	                        'type' =>1,
	                        'money'=>$sMoney,
	                    ];
                        $addInfo = Db::name('share_profit')->insert($faPArr);
                        if (!$addInfo){
                            Db::rollback();
                            return json_error('操作失败3!');
                        }else{echo '发分润添加成功';}
                        /*$addRedPacket= Db::name('red_packet')->insert($red_packet);
                        if (!$addRedPacket){
                            Db::rollback();
                            return json_error('操作失败4!');
                        }*/
	                }
				}

				# 用户抢包分润
				$sPArr = [];
				$suArr = [];
				foreach ($uSnatchLog as $uSnatK => $uSnatV) 
				{
					# 找到当前红包用户抢记录
					if ($sv['re_id'] == $uSnatV['re_id'])
					{
						if (!$uSnatV['level_path']) continue;
						$pIds 		= array_reverse(explode(',', substr($uSnatV['level_path'],1)));
						$someIds 	= array_slice($pIds, 0, static::$snatchLevel);
						$pMoney 	= $uSnatV['money'] * $sendProfit;
						foreach ($someIds as $key => $value) 
						{
							$sPArr[] 	= [
				                    'user_id' 		=> $value,
				                    'type' 			=> 4,
				                    'level'			=> ++$key,
				                    'note' 			=> '抢 '.$key.' 分润',
				                    'money' 		=> $pMoney,
				                    'create_time' 	=> date('Y-m-d H:i:s')
				                ];
						}
						$sPN = Db::name('share_profit')->insertAll($sPArr);
			            if ($sPN) {$suArr[] = $uSnatV['sl_id'];echo '抢分润添加成功';}else{Db::rollback();return json_error('数据操作失败5');}
					}
					
				}
				$sn = Db::name('snatch_log')->where('re_id',$sv['re_id'])->update(['status' => 1]);
				if (!$sn){Db::rollback();return json_error('数据操作失败6');}
				$redN = Db::name('red_envelope')->where('re_id',$sv['re_id'])->update(['share_status' => 1]);
				if (!$redN) {Db::rollback();return json_error('数据操作失败7');}
				else
				{	echo '红包表分润状态修改成功';Db::commit();
					# 处理发免条数
					$doN++;
				}
				
			}

		} catch (Exception $e) {
			Db::rollback();
		}
		
		echo '处理分润免润条数--'.$doN;
	}
  
  	// 迁移数据表中的冷数据
	public function migrationData()
	{
		$bN = Db::query('create table if not exists ch_snatch_log_bak like ch_snatch_log');
		$rN = Db::query('create table if not exists ch_red_envelope_bak like ch_red_envelope');
		Db::startTrans();
		try {
			$sN 	= Db::query('insert into ch_snatch_log_bak select * from ch_snatch_log where status=1');
			$dN 	= Db::name('snatch_log')->where('status',1)->delete();
			$rN 	= Db::query('insert into ch_red_envelope_bak select * from ch_red_envelope where share_status=1');
			$rdN 	= Db::name('red_envelope')->where('share_status',1)->delete();
			dump('新增');dump($sN);
			dump('删除');dump($dN);
			dump('红包新增');dump($rN);
			dump('红包删除');dump($rdN);
			Db::commit();
		} catch (Exception $e) {
			Db::rollback();
			return '异常回滚';
		}

	}
}
